package com.sumainfor.pc.gmio.service.impl;

import com.qiniu.util.Json;
import com.sumainfor.common.util.DateUtils;
import com.sumainfor.common.util.JsonResult;
import com.sumainfor.common.utlis.CompuUtils;
import com.sumainfor.common.wechat.WeChatConfig;
import com.sumainfor.pc.gmio.dao.HoTenantBillMapper;
import com.sumainfor.pc.gmio.dao.SeBpwMapper;
import com.sumainfor.pc.gmio.feign.Zfeign.ZpcMktFeign;
import com.sumainfor.pc.gmio.feign.Zfeign.ZzuulFeign;
import com.sumainfor.pc.gmio.feign.ZuulFeign.ZuulFeign;
import com.sumainfor.pc.gmio.service.HoTenantBillService;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 服务管家租客管理
 */
@Service
public class HoTenantBillSerivceImpl implements HoTenantBillService {

    private ReentrantLock lock = new ReentrantLock(false);
    Logger log = LoggerFactory.getLogger(HoTenantBillSerivceImpl.class);
    @Autowired
    private HoTenantBillMapper hoTenantBillMapper;
    @Autowired
    private ZpcMktFeign zpcMktFeign;
    @Autowired
    private ZzuulFeign zzuulFeign;
    @Autowired
    private ZuulFeign zuulFeign;
    @Autowired
    private SeBpwMapper seBpwMapper;

    /**
     * 根据租客编号查询账单列表
     */
    @Override
    public List<Map<String, Object>> getTenantBillListByTenId(Map<String, Object> params) {
        return hoTenantBillMapper.getTenantBillListByTenId(params);
    }

    /**
     * 根据租客编号查询账单列表总数
     */
    @Override
    public Integer getTenantBillListCountByTenId(Map<String, Object> params) {
        return hoTenantBillMapper.getTenantBillListCountByTenId(params);
    }

    /**
     * 服务管家查询账单中心列表
     */
    @Override
    public List<Map<String, Object>> getHoTenantBillList(Map<String, Object> params) {
        //运营部根据参数查询账单
        List<Map<String, Object>> gmioList = hoTenantBillMapper.getHoTenantBillList(params);
        //b保存录入账单的服务秘书的编号
        List<String> houInfoIdList = new ArrayList<String>();
        for (Map<String, Object> map : gmioList) {
            if (map.get("HouInfoId") != null) {
                houInfoIdList.add(map.get("HouInfoId").toString());
            }
        }
        params.put("houInfoIdList", houInfoIdList);
        //去市场部查询相关的账单的houseInfo和name等信息
        JsonResult result = zpcMktFeign.getHoPactList(params);
        if (result.get("errorCode").toString().equals("0")) {
            List<Map<String, Object>> marketList = (List<Map<String, Object>>) result.get("result");
            for (Map<String, Object> marketMap : marketList) {
                for (Map<String, Object> gmioMap : gmioList) {
                    if (MapUtils.getString(marketMap, "HouInfoId").equals(MapUtils.getString(gmioMap, "HouInfoId"))) {
                        gmioMap.putAll(marketMap);
                    }
                }
            }
        }
        return gmioList;
    }

    /**
     * 服务管家查询账单中心列表总数
     */
    @Override
    public Integer getHoTenantBillListCount(Map<String, Object> params) {
        return hoTenantBillMapper.getHoTenantBillListCount(params);
    }

    /**
     * 填写退租表时查询未缴费账单
     */
    @Override
    public List<Map<String, Object>> getTenantBillWithdraList(Map<String, Object> params) {
        List<Map<String, Object>> gmioList = hoTenantBillMapper.getTenantBillWithdraList(params);
        List<String> usrList = new ArrayList<String>();
        for (Map<String, Object> map : gmioList) {
            System.out.println("map:" + map);
            if (map.get("Create") != null && map.get("CreateType").toString().equals("2")) {
                usrList.add(map.get("Create").toString());
            }
        }
        System.out.println("usrList：" + usrList);
        if (usrList.size() > 0) {
            params.put("usrList", usrList);
            JsonResult zuulResult = zzuulFeign.getUsrList(params);
            System.out.println("zuulResult:" + zuulResult);
            if (zuulResult.get("errorCode").equals("0")) {
                List<Map<String, Object>> zuulList = (List<Map<String, Object>>) zuulResult.get("result");
                for (Map<String, Object> giomap : gmioList) {
                    if (giomap.get("Create") != null) {
                        for (Map<String, Object> zuulmap : zuulList) {
                            if (zuulmap.get("UsroId") != null) {
                                if (MapUtils.getString(giomap, "Create").equals(MapUtils.getString(zuulmap, "UsroId"))) {
                                    giomap.putAll(zuulmap);
                                }
                            }
                        }
                    }
                }
            }
        }
        return gmioList;
    }

    /*
     *退租账单根据客户编号和房源详表编号查询合同已产生的金额
     */
    @Override
    public JsonResult getHoProduceMoney(Map<String, Object> params) {
        JsonResult result = new JsonResult();
        if (params.get("Source") == null || params.get("TenId") == null || params.get("HouInfoId") == null
                || params.get("EndTime") == null || params.get("PaActMonthPrice") == null || params.get("StartTime") == null
                || params.get("PaMonthPrice") == null || params.get("Pmethod") == null
        ) {
            return result.putFailed("参数不正确");
        }
        //查询合同的总金额
        Map<String, Object> map = hoTenantBillMapper.getHoProduceMoney(params);
        //查询合同相关的房租账单列表
        String nowTime = DateUtils.getNowTime("yyyy-MM-dd");//当前时间
        String endTime = params.get("EndTime").toString();//合同结束时间
        String StartTime = params.get("StartTime").toString();//合同开始时间
        Integer ifRent = 0;//0 违约退 1 正常退
        Integer ifDay = 0;//0 未到合同开始时间 1 已经到了合同开始时间
        Integer monthCount = 0;//需要整月退租金给租客的月数
        Integer dayCount = 0;//退租时间与合同截止时间相差的月数
//        Integer pactCout=DateUtils.getMonthDiff(nowTime,endTime,"yyyy-MM-dd");//合同周期（单位：月）

        BigDecimal pactMoney = new BigDecimal(params.get("PaActMonthPrice").toString());//合同月租金
        BigDecimal dayMoney = new BigDecimal("0");//日租金
        BigDecimal retireMoney = new BigDecimal("0");//应退金额
        BigDecimal PaidBiMoney = new BigDecimal(map.get("PaidBiMoney").toString());//已支付的房租金额
        BigDecimal ProBiMoney = new BigDecimal(map.get("ProBiMoney").toString());//已产生的费用
        System.out.println("已产生费用：" + PaidBiMoney);
        System.out.println("房屋押金：" + params.get("PaMonthPrice"));
        System.out.println("每月房租：" + pactMoney);
        //（已支付房租减去已产生费用）/每月房租
        Integer pactCout = PaidBiMoney.subtract(ProBiMoney).divide(pactMoney, 0).intValue();//合同周期（单位：月）
        System.out.println("pactCout前：" + pactCout);
        pactCout = pactCout == 0 ? 1 : pactCout;
        String pmethod = String.valueOf(params.get("Pmethod"));
        if (pmethod.equals("0")) {//月付
            pactCout = 1 * pactCout;
        } else if (pmethod.equals("1")) {//季付
            pactCout = 3 * pactCout;
        } else if (pmethod.equals("2")) {//半年付
            pactCout = 6 * pactCout;
        } else if (pmethod.equals("3")) {//年付
            pactCout = 12 * pactCout;
        }
        System.out.println("pactCout后：" + pactCout);
        //判断已产生费用是否大于已支付费用
        monthCount = pactCout > 0 ? Math.abs(pactCout) : 0;
        // 2 违约退 0、1正常退 (当前时间与合同结束时间比较)
        if (DateUtils.compare_date(nowTime, endTime, "yyyy-MM-dd").equals("2")) {
            ifRent = 0;
            // (当前时间与合同开始时间比较)//还没有到合同开始时间
            if (DateUtils.compare_date(nowTime, StartTime, "yyyy-MM-dd").equals("2")) {
                retireMoney = PaidBiMoney;
                ifDay = 0;
            } else {//到了合同开始时间
                ifDay = 1;
                dayCount = Math.abs(DateUtils.betweenDay(nowTime, endTime));
                /*********获取租金*********/
                //判断两个时间是否在一个月内 true 同一个月  false 不在同一个月
                Boolean ifDateOfMonth = DateUtils.checkMonth(nowTime, endTime);
                if (ifDateOfMonth) {//在同一个月
                    //获取时间所在的月份有多少天
                    Integer count = DateUtils.getMonthOfDay(endTime);
                    //合同月租金/延期开始时间所在的月份天数(除法 四舍五入 保留两位小数)
                    dayMoney = pactMoney.divide(new BigDecimal(String.valueOf(count)), 2, BigDecimal.ROUND_HALF_UP);

                } else {//不在同一个月
                    //获取延期开始时间月份的天数
                    Integer beginCount = DateUtils.getMonthOfDay(nowTime);
                    //获取延期结束时间月份的天数
                    Integer endCount = DateUtils.getMonthOfDay(endTime);
                    //计算延期开始时间和延期开始时间所在月的最后一天相差天数
                    Integer beginDayCount = DateUtils.betweenDay(nowTime, DateUtils.getMonthLastDay(nowTime));
                    //计算延期结束时间和延期结束时间所在月的第一天相差天数
                    Integer endDayCount = DateUtils.betweenDay(DateUtils.getMonthFirstDay(endTime), endTime);
                    //（ (2000/31) X4+(2000/30)x3）/7 上半金额
                    BigDecimal beginMoney = pactMoney.divide(new BigDecimal(String.valueOf(beginCount)), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(String.valueOf(beginDayCount)));
                    //下半金额
                    BigDecimal endMoney = pactMoney.divide(new BigDecimal(String.valueOf(endCount)), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(String.valueOf(endDayCount)));
                    //延期日租金
                    dayMoney = (beginMoney.add(endMoney)).divide(new BigDecimal(String.valueOf(beginDayCount + endDayCount)), 2, BigDecimal.ROUND_HALF_UP);
                }
            }

        } else if (DateUtils.compare_date(nowTime, endTime, "yyyy-MM-dd").equals("2") || DateUtils.compare_date(nowTime, endTime, "yyyy-MM-dd").equals("3")) {
            ifRent = 1;
        } else {
            return result.putFailed("服务器繁忙");
        }
        //计算应退金额(月数*合同月租金)+（天数*日租金）
//        System.out.println("nowTime"+nowTime);
//        System.out.println("endTime:"+endTime);
//        System.out.println("DateUtils.compare_date(nowTime,endTime,\"yyyy-MM-dd\"):"+DateUtils.compare_date(nowTime,endTime,"yyyy-MM-dd"));
//        System.out.println("比较时间大小"+DateUtils.compare_date(nowTime,endTime,"yyyy-MM-dd").equals("1"));
//        System.out.println("monthCount:"+monthCount);
//        System.out.println("dayCount:"+dayCount);
//        System.out.println("pactMoney:"+pactMoney);
//        System.out.println("pactCout:"+pactCout);
        if (monthCount > 1) {
            monthCount--;
            retireMoney = retireMoney.add(pactMoney.multiply(new BigDecimal(monthCount)));
        }
        if (dayCount > 0) {
            retireMoney = retireMoney.add(dayMoney.multiply(new BigDecimal(dayCount)));
        }
        System.out.println("pactMoney.multiply(new BigDecimal(pactCout-1)):" + pactMoney.multiply(new BigDecimal(monthCount - 1)));
        map.put("ifRent", ifRent);
        map.put("monthCount", monthCount);
        map.put("dayCount", dayCount);
        map.put("dayMoney", dayMoney);
        map.put("retireMoney", retireMoney);
        map.put("ifDay", ifDay);
//        map.put("pactCout",pactCout);
        result.put(map);
        return result;
    }

    /**
     * 续签的时候查询上一份合同的全部未支付账单
     */
    @Override
    public JsonResult getHoUnpaidBillList(Map<String, Object> params) {
        JsonResult result = new JsonResult();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        BigDecimal total_fee = new BigDecimal("0");//保存账单总价
        Map<String, String> paramsXml = new HashMap<String, String>();
        if (params.get("Source") == null || params.get("AreaId") == null) {
            return result.putFailed("参数不正确");
        }
        //获取权限当前公司的微信支付
        JsonResult zuulResult = zuulFeign.getAreaPayMap(params);
        if (!zuulResult.get("errorCode").toString().equals("0")) {
            //如果查询不到就用默认的商户号
            paramsXml.put("mch_id", WeChatConfig.DEFAULT_MCH_ID);//商户号
            dataMap.put("mch_id", paramsXml.get("mch_id"));
            dataMap.put("sub_mch_id", "");
            dataMap.put("ServeType", "2");
        } else {
            Map<String, Object> zuulMap = (Map<String, Object>) zuulResult.get("result");
            //支付模式      1.服务商模式   2.普通商户\n普通商户没有父商户号
            if (zuulMap.get("ServeType").toString().equals("1")) {
                paramsXml.put("mch_id", zuulMap.get("SubMchId").toString());//商户号
                paramsXml.put("sub_mch_id", zuulMap.get("MchId").toString());//商户号
                dataMap.put("mch_id", paramsXml.get("mch_id"));
                dataMap.put("sub_mch_id", paramsXml.get("sub_mch_id"));
            } else {
                paramsXml.put("mch_id", zuulMap.get("MchId").toString());//商户号
                dataMap.put("mch_id", paramsXml.get("mch_id"));
                dataMap.put("sub_mch_id", "");
            }
            dataMap.put("ServeType", zuulMap.get("ServeType"));
        }
        //查询租客上一份合同的未支付的账单信息
        List<Map<String, Object>> unPaidList = hoTenantBillMapper.getHoUnpaidBillList(params);
        if (unPaidList == null) {
            unPaidList = new ArrayList<Map<String, Object>>();
        }
        //计算本次支付的总和
        for (Map<String, Object> unPaidMap : unPaidList) {
            total_fee = total_fee.add(new BigDecimal(unPaidMap.get("BiMoney").toString()));
        }
        //查询是否已经有预订单信息如果没有再去请求微信的预订单接口
        //iFseBpw 0没有微信订单信息  1有微信订单信息
        Map<String, Object> signMap = seBpwMapper.getSeBpw(params);
        if (signMap == null) {
            dataMap.put("iFseBpw", "0");
        } else {
            // IfCoucode 0未使用优惠卷 1使用了优惠卷
            if (signMap.get("IfCoucode") != null && signMap.get("IfCoucode").toString().equals("1")) {
                //如果使用了优惠卷就减去优惠卷的值
                total_fee = total_fee.subtract(new BigDecimal(signMap.get("Facevalue").toString()));
                dataMap.put("Facevalue", "Facevalue");
            }
            dataMap.put("iFseBpw", "1");
            dataMap.put("signMap", signMap);
            dataMap.put("Coucode", signMap.get("Coucode"));//优惠卷的编号
            dataMap.put("IfCoucode", signMap.get("IfCoucode"));// 0未使用优惠卷 1使用了优惠卷
        }
        dataMap.put("unPaidList", unPaidList);//未支付的账单列表
        dataMap.put("total_fee", total_fee);//账单金额
        return result.put(dataMap);
    }

    /**
     * 租客端续签的时候查询续签合同的信息
     */
    @Override
    public JsonResult getRenUnifiedPact(Map<String, Object> params) {
        JsonResult result = new JsonResult();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        BigDecimal total_fee = new BigDecimal("0");//保存账单总价
        //优惠卷面值
        BigDecimal bigFacevalue = new BigDecimal("0");
        //组装请求微信预订单用的参数
        Map<String, String> paramsXml = new HashMap<String, String>();
        if (params.get("Source") == null) {
            return result.putFailed("参数不正确");
        }
        //获取权限当前公司的微信支付
        JsonResult zuulResult = zuulFeign.getAreaPayMap(params);
        if (!zuulResult.get("errorCode").toString().equals("0")) {
            //如果查询不到就用默认的商户号
            dataMap.put("mch_id", WeChatConfig.DEFAULT_MCH_ID);//商户号
            dataMap.put("sub_mch_id", "");//商户号
            dataMap.put("ServeType", "2");
        } else {
            Map<String, Object> zuulMap = (Map<String, Object>) zuulResult.get("result");
            //支付模式      1.服务商模式   2.普通商户\n普通商户没有父商户号
            if (zuulMap.get("ServeType").toString().equals("1")) {
                dataMap.put("mch_id", zuulMap.get("SubMchId").toString());//商户号
                dataMap.put("sub_mch_id", zuulMap.get("MchId").toString());//商户号
            } else {
                dataMap.put("mch_id", zuulMap.get("MchId").toString());//商户号
                dataMap.put("sub_mch_id", "");//商户号
            }
            dataMap.put("ServeType", zuulMap.get("ServeType"));
        }
        //到市场部查询续签合同的信息
        JsonResult marketResult = zpcMktFeign.getRdRenPactInfo(params);
        System.out.println("返回市场部的数据:" + marketResult);
        if (marketResult.get("errorCode").toString().equals("0")) {
            Map<String, Object> marketMap = (Map<String, Object>) marketResult.get("result");
            //判断合同的支付方式  0月付 1 季付 2 半年付 3年付
            BigDecimal pCount = new BigDecimal("1");//每期租金支付几个月
            if (marketMap.get("Pmethod").toString().equals("0")) {
                pCount = new BigDecimal("1");
            } else if (marketMap.get("Pmethod").toString().equals("1")) {
                pCount = new BigDecimal("3");
            } else if (marketMap.get("Pmethod").toString().equals("2")) {
                pCount = new BigDecimal("6");
            } else if (marketMap.get("Pmethod").toString().equals("3")) {
                pCount = new BigDecimal("12");
            }
            //实际签约价格
            BigDecimal bigPaActMonthPrice = new BigDecimal(marketMap.get("PaActMonthPrice").toString());
            //首月的水电押金
            BigDecimal bigWaDeposit = new BigDecimal(marketMap.get("WaDeposit").toString());
            //房屋押金押几个月
            BigDecimal bigDeposit = new BigDecimal(marketMap.get("Deposit").toString());
            //合同月租金
            BigDecimal bigPaMonthPrice = new BigDecimal(marketMap.get("PaMonthPrice").toString());
            System.out.println("pCount:" + pCount);
            System.out.println("bigPaActMonthPrice.multiply(pCount):" + bigPaActMonthPrice.multiply(pCount));
            System.out.println("bigWaDeposit.multiply(bigDeposit):" + bigWaDeposit.multiply(bigDeposit));
            //房屋总价=实际签约价格*每期需要付几个月 +房源押金+房源的水电押金
            total_fee = bigPaActMonthPrice.multiply(pCount).add(bigPaMonthPrice.multiply(bigDeposit)).add(bigWaDeposit);
            dataMap.putAll(marketMap);//续签的合同信息
        }
        //计算本次支付的总和(减去优惠卷的面额)
        total_fee = total_fee.subtract(bigFacevalue);
        System.out.println("total_fee:" + total_fee);
        System.out.println("bigFacevalue:" + bigFacevalue);

        //查询是否已经有预订单信息如果没有再去请求微信的预订单接口
        Map<String, Object> signMap = seBpwMapper.getSeBpw(params);
        if (signMap == null) {
            dataMap.put("iFseBpw", "0");

        } else {
            // IfCoucode 0未使用优惠卷 1使用了优惠卷
            if (signMap.get("IfCoucode").toString().equals("1")) {
                //如果使用了优惠卷就减去优惠卷的值
                total_fee = total_fee.subtract(new BigDecimal(signMap.get("Facevalue").toString()));
                signMap.put("Facevalue", "Facevalue");
            }
            dataMap.put("iFseBpw", "1");
            dataMap.put("signMap", signMap);
            dataMap.put("IfCoucode", "IfCoucode");
        }
        dataMap.put("total_fee", total_fee);//账单金额
        return result.put(dataMap);
    }

    /**
     * 根据账单来源编号查询账单的相关信息（维修师傅我的工单的账单详细）
     */
    @Override
    public JsonResult getBillListForReapir(Map<String, Object> params) {
        JsonResult result = new JsonResult();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        BigDecimal billMoney = new BigDecimal("0");//应收金额
        BigDecimal payBillMoney = new BigDecimal("0");//实收金额
        if (params.get("Source") == null) {
            return result.putFailed("参数不正确");
        }
        List<Map<String, Object>> list = hoTenantBillMapper.getBillListForReapir(params);
        if (list != null) {
            resultMap.put("list", list);
        } else {
            resultMap.put("list", new ArrayList<>());
        }
        //计算实收金额
        for (Map<String, Object> billMap : list) {
            //Status 账单状态   1.待支付  2.支付完成  3待审核   4.账单废弃（租客违约）5审核驳回
            if (billMap.get("Status") != null && String.valueOf(billMap.get("Status").toString()).equals("2")
                    && billMap.get("BiMoney") != null && !String.valueOf(billMap.get("BiMoney").toString()).equals("")) {
                billMoney = billMoney.add(new BigDecimal(billMap.get("BiMoney").toString()));
            }
            if (billMap.get("PayMoney") != null && !String.valueOf(billMap.get("PayMoney").toString()).equals("")) {
                payBillMoney = payBillMoney.add(new BigDecimal(billMap.get("PayMoney").toString()));
            }

        }

        //应收金额 是否大于 实收金额
        if (billMoney.compareTo(payBillMoney) == 1) {
            //billStatus 0 未支付完成 1 支付完成 2实收金额 大于 应收金额
            resultMap.put("billStatus", 0);
            resultMap.put("billName", "未支付完成");
        }
        //应收金额 等于 实收金额
        else if (billMoney.compareTo(payBillMoney) == 0) {
            resultMap.put("billStatus", 1);
            resultMap.put("billName", "支付完成");
        } else {
            resultMap.put("billStatus", 2);
            resultMap.put("billName", "支付金额溢出");
        }
        resultMap.put("billMoney", billMoney);
        resultMap.put("payBillMoney", payBillMoney);
        System.out.println("resultMap:" + resultMap);
        result.put(resultMap);
        System.out.println("result:" + result);
        return result;
    }

    /**
     * 续租的时候查询上次合同未支付的账单
     * @param params
     * @return
     */
    @Override
    public JsonResult getPaIdNoBill(Map<String, Object> params) {
        JsonResult result =new JsonResult();
        Map<String,Object> map1 = new HashMap<>();

        Double total_fee = new Double("0");//未缴费用的全部金额
        List<Map<String,Object>> unPaidList = hoTenantBillMapper.getPaIdNoBill(params);
           if (unPaidList.size()>0&&unPaidList !=null){
               for (Map<String,Object> map2:unPaidList){
                   total_fee = CompuUtils.add(total_fee,MapUtils.getDouble(map2,"BiMoney"));
               }
           }

           map1.put("total_fee",total_fee);
           map1.put("unPaidList",unPaidList);
           return result.put(map1);

    }

//    public static void main(String[] args) {
//        System.out.println("合同周期:"+DateUtils.getMonthDiff("2019-09-01","2020-09-02","yyyy-MM-dd"));
//
//        System.out.println("需要付款的天数:"+Math.abs(DateUtils.betweenDay("2019-09-01","2020-08-31")));
//    }
}
